package net.sharpf2.api.world;

import java.awt.Point;
import java.util.ArrayList;
import net.sharpf2.api.content.WorldObject;
import net.sharpf2.sfcore.client.AnimableNode;
import net.sharpf2.sfcore.client.AnimableObject;
import net.sharpf2.api.Methods;
import net.sharpf2.api.types.Content;

/**
 *
 * @author Rick van Biljouw
 */
public class Objects {

    /**
     * Gets an object at a specified tile.
     * @param   x Tile.
     * @param   y Tile.
     * @return  Array of objects at the specified tile.
     */
    public static ArrayList<Content<WorldObject>> getObjectsAt(int x, int y) {
        ArrayList<Content<WorldObject>> objectList = new ArrayList<Content<WorldObject>>();
        net.sharpf2.sfcore.client.Ground ground = Ground.getTile(x, y, Methods.getClient().getPlane());

        if (ground.getWallObject() != null && ground.getWallObject().getId() > 0) {
            objectList.add(new Content<WorldObject>(ground.getWallObject()));
        }

        if (ground.getWallObject2() != null && ground.getWallObject2().getId() > 0) {
            objectList.add(new Content<WorldObject>(ground.getWallObject2()));
        }
        
        if(ground.getFloorDecoration() != null && ground.getFloorDecoration().getId() > 0) {
            objectList.add(new Content<WorldObject>(ground.getFloorDecoration()));
        }

        AnimableObject object;
        for (AnimableNode node = ground.getAnimableList(); node != null; node = node.getNext()) {
            object = node.getAnimable();
            if (object != null) {
                if (object.getId() != -1) {
                    objectList.add(new Content<WorldObject>(object));
                }
            }
        }

        return objectList;
    }
    
    /**
     * Gets all objects.
     * @return Array of objects.
     */
    public static ArrayList<Content<WorldObject>> getAll() {
        ArrayList<Content<WorldObject>> objectList = new ArrayList<Content<WorldObject>>();
        
        for(int i = 0; i < 104; i++) {
            for(int j = 0; j < 104; j++) {
                ArrayList<Content<WorldObject>> tileObjectList = getObjectsAt(i, j);
                if(tileObjectList.size() > 0) {
                    objectList.addAll(tileObjectList);
                }
            }
        }
        
        return objectList;
    }
    
    /**
     * Gets all objects in a specified radius.
     * @param   radius Radius.
     * @return  Array of objects.
     */
    public static ArrayList<Content<WorldObject>> getAll(int radius) {
        ArrayList<Content<WorldObject>> objectList = new ArrayList<Content<WorldObject>>();
        
        Point worldPos = Methods.getMyPlayer().getContent().getWorldPosition();
        
        for(Content<WorldObject> object : getAll()) {
            if(object.getContent().getWorldPosition().distance(worldPos) <= radius) {
                objectList.add(object);
            }
        }
        
        return objectList;
    }    
    
    /**
     * Gets the nearest object with the specified id.
     * @param   ids Object ids.
     * @return  Content<WorldObject>
     */
    public static Content<WorldObject> getNearest(int... ids) {
        Content<WorldObject> best = null;           
        int cDist = 9999;
        
        for(Content<WorldObject> object : getAll()) {
            for(int id : ids) {
                if(object.getContent().getId() == id) {
                    int tDist = (int) object.getContent().getWorldPosition().distance(Methods.getMyPlayer().getContent().getWorldPosition());
                    if(tDist < cDist) {
                        best = object;
                        cDist = tDist;
                    }
                }
            }
        }
                
        return best;
    }
}
